/*
 * =====================================================================================
 *
 *       Filename:  cl_pc_queue.hxx
 *
 *    Description:  A prodcuer-consumer queue
 *
 *        Version:  1.0
 *        Created:  12/11/2010 09:54:50 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Chen Ken (Ken), zlchen.ken@gmail.com
 *        Company:  EMC
 *
 * =====================================================================================
 */

#ifndef _CL_PC_QUEUE_HXX_
#define _CL_PC_QUEUE_HXX_

#include <utility>
#include <queue>
#include "cl_cond_mutex.hxx"
#include "cl_lock_guard.hxx"

namespace neo
{
template<typename T>
class CLProducerConsumerQueue
{
public:
	CLProducerConsumerQueue() 
  {
  }

	~CLProducerConsumerQueue() 
  {
  }

	void push(T&& t) 
  {
    CLLockGuard guard(m_condMutex);
	  m_msgQueue.push(std::move(t));
    m_condMutex.notify();
  }

	void push(const T& t) 
  {
    CLLockGuard guard(m_condMutex);
	  m_msgQueue.push(t);
    m_condMutex.notify();
  }

  bool pop(T& t) 
  {
    CLLockGuard guard(m_condMutex);

    while(m_msgQueue.empty())
    {
      m_condMutex.wait();
    }
	  t = T(std::move(m_msgQueue.front()));
	  m_msgQueue.pop();

	  return true;
  }

private:
	CLProducerConsumerQueue(const CLProducerConsumerQueue&);
	CLProducerConsumerQueue& operator=(const CLProducerConsumerQueue& other);

private:
  CLCondMutex m_condMutex;
	typedef std::queue<T> PCQueue;
	PCQueue m_msgQueue;
};

} // neo

#endif //_CL_PC_QUEUE_HXX_

